#include "user_main.h"

static const char *TAG = "demo";

int shortdown(void)
{
	ESP_LOGW(TAG, "===== SHOART DOWN =====");
	return 0;
}
	
int longdown(void)
{
	ESP_LOGW(TAG, "===== LONG DOWN =====");
	return 0;
}

void system_monitor(void *argv)
{
	Gpio_Init();
	set_key_shortDown_callback(200, shortdown);
	set_key_longDown_callback(2000, longdown);

	while (1)
	{
		KEY_scanf();
		LED_control();
		vTaskDelay(100/portTICK_RATE_MS);
	}
}

void Networl_init(void)
{
	my_wifi_t wifi_info = {
		.ssid = "ESP8266",
		.max_connection = 1,
	};

	ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
	wifi_init_softap(&wifi_info);
}

void HeapStack_monitor(void *argv)
{
	task_handle_managa_t *task_handle_cur = NULL;
	task_handle_managa_t *task_handle_haed = get_task_handle_haed();
	while (1)
	{
		printf("\n");
		ESP_LOGI(TAG, "free_heap_size: %d KB", esp_get_free_heap_size() / 1024);
		ESP_LOGI(TAG, "minimum_free_heap_size: %d KB", esp_get_minimum_free_heap_size() / 1024);

		for (task_handle_cur = task_handle_haed; task_handle_cur != NULL; 
				task_handle_cur = task_handle_cur->next)
		{
			if (task_handle_cur->handle != NULL) {
				ESP_LOGI(TAG, "%s stack:%d B", task_handle_cur->name, uxTaskGetStackHighWaterMark(task_handle_cur->handle) * 4);
			}
		}
		printf("\n");
		vTaskDelay(1000/portTICK_PERIOD_MS);
	}
}

void user_nvs_init(void)
{
	esp_err_t err = nvs_flash_init();
	if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
		ESP_ERROR_CHECK(nvs_flash_erase());
		err = nvs_flash_init();
	}
	ESP_ERROR_CHECK( err );

	nvs_handle my_handle;
	err = nvs_open("storage", NVS_READWRITE, &my_handle);
	if (err != ESP_OK) {
		printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
	} 
	int32_t restart_counter = 0;
	err = nvs_get_i32(my_handle, "restart_counter", &restart_counter);
	switch (err) {
		case ESP_OK:
			printf("Restart counter = %d\n", restart_counter);
			break;
		case ESP_ERR_NVS_NOT_FOUND:
			printf("The value is not initialized yet!\n");
			break;
		default :
			printf("Error (%s) reading!\n", esp_err_to_name(err));
	}

	restart_counter++;
	err = nvs_set_i32(my_handle, "restart_counter", restart_counter);
	if (err != ESP_OK)
			printf("Error (%s) seting!\n", esp_err_to_name(err));
	err = nvs_commit(my_handle);
	if (err != ESP_OK)
			printf("Error (%s) seting!\n", esp_err_to_name(err));
	nvs_close(my_handle);
}

static httpd_handle_t server = NULL;

void http_server_task(void)
{
	while (1)
	{
		EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
				WIFI_STACONNECTED_BIT | WIFI_STADISCONNECTED_BIT,
				pdTRUE,
				pdFALSE,
				portMAX_DELAY);
		vTaskDelay(100/portTICK_PERIOD_MS);

		if (bits & WIFI_STACONNECTED_BIT) {
			if (server == NULL) {
				ESP_LOGI(TAG, "Starting webserver");
				server = start_webserver();
			}
		}
		else if(bits & WIFI_STADISCONNECTED_BIT) {
			ESP_LOGI(TAG, "stop webserver");
			if (server != NULL)
				stop_webserver(server);
		}
	}
}

void app_main()
{
	system_status_t *sys_sta = get_sys_sta();
	const esp_app_desc_t *app_desc = esp_ota_get_app_description();
	sys_sta->version = (char *)app_desc->version;
	ESP_LOGI(TAG, "app_version:%s", sys_sta->version); 

	user_nvs_init();

	printf("free_heap_size: %d KB\n", esp_get_free_heap_size() / 1024);
	printf("minimum_free_heap_size: %d KB\n", esp_get_minimum_free_heap_size() / 1024);

	new_task(HeapStack_monitor, "HeapStack_monitor", 1024, NULL, 21);
	new_task(system_monitor, "system_monitor", 1024, NULL, 23);

	ESP_LOGI(TAG, "init ap mode");
	Networl_init();
	ESP_LOGI(TAG, "Run");

	http_server_task();
}
